package lzupdater.utils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import lzupdater.com.CommunicationHub;
import lzupdater.com.HubComponent;
import lzupdater.locale.Dictionary;
import lzupdater.locale.Locale;
import lzupdater.locale.LocalizedString;
import lzupdater.log.Logger;
import lzupdater.log.LoggerLevel;
import lzupdater.properties.PropertiesManager;
import lzupdater.properties.PropertyElement;
import lzupdater.properties.PropertyElement.HashMapProperty;

//LZRosterUpdater, a java client to update LZRoster
//Copyright (C) 2008 Fraskor from Krasus (e-mail: fraskor@gmail.com)
//
//This file is part of LZRosterUpdater.
//
//LZRosterUpdater is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

/**
 * 
 * @author Fraskor
 */
public class LZUPreferences extends HubComponent {

	private final static LocalizedString errorReadingPreferenceFile = new LocalizedString(
			"Error when reading preferences from file '%s'");
	private final static LocalizedString noPreferenceFound = new LocalizedString(
			"No preference found in the preference file.");

	private final static String preferenceDir = "preferences";
	private final static String profileDir = "profiles";
	private final static String langDir = "lang";
	private final static String verboseDir = "verboseLevel";
	private final static String wowPathDir = "wowPath";
	
	private String preferenceFile = null;

	private String lang;
	private LoggerLevel logLevel;
	private String wowRootPath;

	private LZUProfileManager profileManager = null;
	private Logger logger = null;

	private ArrayList<LZUPreferencesListener> listeners = new ArrayList<LZUPreferencesListener>();

	public LZUPreferences(CommunicationHub hub) {
		super(hub);
		new LZUProfileManager(hub);
	}

	@Override
	public void initializeCommunication() {
		profileManager = hub.getComponent(LZUProfileManager.class);
		logger = hub.getComponent(LZULogger.class);
	}

	@Override
	public void initialize() {
		lang = Dictionary.getCurrentLocale().toString();
		logLevel = LoggerLevel.INFO;
		wowRootPath = "";
	}

	public void load() {
		try {
			HashMapProperty root = PropertiesManager.load(preferenceFile,
					logger);

			HashMapProperty profileProperties = root.getAsMap(profileDir);
			HashMapProperty preferenceProperties = root.getAsMap(preferenceDir);

			if (preferenceProperties == null) {
				logger.warning(noPreferenceFound.toString());
			} else {
				setLang(preferenceProperties.getAsString(langDir, lang));
				setLogLevel(LoggerLevel.setFrom(preferenceProperties
						.getAsString(verboseDir, "INFO")));
				setWowRootPath(preferenceProperties.getAsString(wowPathDir,""));				
			}

			profileManager.load(profileProperties);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(errorReadingPreferenceFile
					.useAsFormater(preferenceFile));
			profileManager.setDefault();
		}

	}

	public void save() throws IOException {
		HashMapProperty root = PropertyElement.makeHashMapProperty();
		root.clear();

		HashMapProperty preferenceProperties = root.getOrAddDir(preferenceDir);

		preferenceProperties.addProperty(langDir, lang);
		preferenceProperties.addProperty(verboseDir, logLevel.toString());
		preferenceProperties.addProperty(wowPathDir, wowRootPath);
		
		profileManager.save(root.getOrAddDir(profileDir));

		PropertiesManager
				.save(
						"# LZTosterUpdater preferences. Automatically generated. Do not modify",
						root, preferenceFile, logger);

	}

	public void addPreferencesListener(LZUPreferencesListener listener) {
		if (!listeners.contains(listener)) {
			listeners.add(listener);
		}
	}

	private void firePreferencesUpdate() {
		for (LZUPreferencesListener l : listeners) {
			l.preferencesUpdated(this);
		}
	}

	public String getLang() {
		return lang;
	}

	public void setLang(String lang) {
		String oldLang = this.lang;
		this.lang = lang;
		Dictionary.setCurrentLanguage(new Locale(this.lang));
		if (!oldLang.equals(this.lang)) {
			firePreferencesUpdate();
		}
	}

	public LoggerLevel getLogLevel() {
		return logLevel;
	}

	public void setLogLevel(LoggerLevel logLevel) {
		LoggerLevel oldLevel = this.logLevel;
		this.logLevel = logLevel;

		if (oldLevel != this.logLevel) {
			firePreferencesUpdate();
		}
	}

	public void setWowRootPath(String path) {
		String oldPath = this.wowRootPath;
		this.wowRootPath = path;
		if (oldPath == null || !oldPath.equals(this.wowRootPath)) {
			firePreferencesUpdate();
		}
	}
	

	public boolean isWowRootPathValide() {
		if (this.wowRootPath == null) return false;
		if (!(new File(WoWPathGuesser.getInstance().getExecutablePath(this.wowRootPath))).exists()) {
			return false;
		}
		return true;
	}
	
	
	public String getWowRootPath() {
		if (!isWowRootPathValide()) {
			String tmp = WoWPathGuesser.getInstance().getRootPathOrAsk();
			this.setWowRootPath(tmp);
		}
		return wowRootPath;
	}

	/**
	 * @return the preferenceFile
	 */
	public String getPreferenceFile() {
		return preferenceFile;
	}

	/**
	 * @param preferenceFile
	 *            the preferenceFile to set
	 */
	public void setPreferenceFile(String preferenceFile) {
		this.preferenceFile = preferenceFile;
	}
}
